home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 11
/
PC World Interactive 11.iso
/
share
/
convert
/
cel2pcx.lzh
/
CEL2PCX.CPP
next >
Wrap
C/C++ Source or Header
|
1994-03-13
|
5KB
|
190 lines
#include <fstream.h>
#include <malloc.h>
#include <string.h>
#include "pcx2cel.h"
#define BSIZE 16384
#define HIMASK 0xF0
#define LOMASK 0xF
byte Palblock[768];
pcxHeader PcxH;
void headerInit() {
PcxH.maker=0xA;
PcxH.version=5;
PcxH.code=1;
PcxH.bpp=8;
PcxH.x1=0; PcxH.y1=0;
PcxH.hres=0x96;
PcxH.vres=0x96;
for (int i=0; i<48; i++)
PcxH.tripletData[i]=Palblock[i+1]; //16 col palette area.
PcxH.vmode=0;
PcxH.numPlanes=1;
PcxH.paletteFlag=1;
for (i=0; i<58; i++)
PcxH.unusedData[i]=0;
}
int readKCF(char *in) {
byte *paltemp=new byte[320];
byte *poshold=paltemp;
byte *Pblockpos=Palblock;
ifstream myInStream(in, ios::binary);
if (!myInStream) {
cerr << in << ": Cannot open input file\n";
delete paltemp;
return 1;
}
*Pblockpos++=12; //Initial 12 value sep pic from palette.
myInStream.read(paltemp, 320);
for (int i=0; i<160; i++) {
*Pblockpos++=(HIMASK & *poshold); //mult by 16 upper nibble; R
*Pblockpos++=(LOMASK & *(poshold+1)) <<4; //mult by 16 lower nibble; G
*Pblockpos++=(LOMASK & *poshold) <<4; // B value
poshold+=2; }
for (i=0; i<288; i++)
*Pblockpos++=0; //zero out remaining entries
myInStream.close();
//At this point, block filled with palvals. Others written will be 0.
return 0;
}
void RLEblock(int &val, int &lastval, long &writecount, int &count, byte *&outpos) {
if (val==lastval) {
count++;
if (count==63){
*outpos++=0xC0 | count; *outpos++=lastval; writecount+=2; count=0;}
} else { //this case, new val trigger.
if (count) {
if (count >1) {
*outpos++=0xC0 | count; *outpos++=lastval; writecount+=2;
} else {
*outpos++=lastval; writecount++; }
lastval=val;
count=1;
}//if (count)
} //else
}
int convertCELPic(char *in, char *out) {
byte *inbuffer=new byte[BSIZE];
byte *outbuffer=new byte[BSIZE*2];
byte buf[128];
byte *inbuf=buf;
struct sizedat{
int width, height;
} sizedata;
sizedat *sizeptr=&sizedata;
ifstream myInStream(in, ios::binary);
if (!myInStream) {
cerr << in << ": Cannot open input file\n";
delete inbuffer;
delete outbuffer;
return 1;}
ofstream myOutStream(out, ios::binary);
if (!myOutStream) {
cerr << out << ": not able to write file.\n";
delete inbuffer;
delete outbuffer;
return 1;}
myInStream.read(inbuf, 4);
memcpy(sizeptr, inbuf, 4);
PcxH.x2=sizeptr->width-1;
PcxH.y2=sizeptr->height-1;
PcxH.bpl=sizeptr->width + sizeptr->width % 2;
//write header block; the breakdown from weirdness.
myOutStream.write((byte *)&PcxH, 128);
//write always <=input block. Keep track of all to write, as well as counter.
//remember that double size of write block due to decompression from nibble
int count=0, val;
long writecount=0, totalread=0;
int linesize=PcxH.bpl>>1;
long readmax;
long readlimit=(BSIZE/linesize)*linesize; //round # of lines.
byte *inpos=inbuffer;
byte *outpos=outbuffer;
int lastval=0;
myInStream.seekg(0, ios::end);
long size = myInStream.tellg();
myInStream.seekg(4, ios::beg);
while (totalread < size) {
if (size-totalread>BSIZE) readmax=readlimit; else readmax=size-totalread;
myInStream.read(inbuffer, readmax);
totalread+=readmax;
for (int i=0; i<readmax; i+=linesize) {
lastval=(HIMASK & *inpos) >>4; //new line, fresh start
for (int j=1; j<=linesize; j++) {
val=(HIMASK & *inpos) >>4;
RLEblock(val, lastval, writecount, count, outpos);
if (count==0) lastval=(LOMASK & *inpos); //last=next.
val=(LOMASK & *inpos);
RLEblock(val, lastval, writecount, count, outpos);
if (count==0) lastval=(HIMASK & *(++inpos)) >>4; else *inpos++;
} //line decode loop
//if remaining vals unwritten, write here. finish off.
if (count) {
if (count >1) {
*outpos++=0xC0 | count; *outpos++=lastval; writecount+=2;
} else {
*outpos++=lastval; writecount++; }
count=0;
}//if (count)
} //buffer decode loop
myOutStream.write(outbuffer, writecount);
writecount=0;
inpos=inbuffer; outpos=outbuffer;
} //while loop
myOutStream.write(Palblock, 769);
delete inbuffer; delete outbuffer;
myInStream.close();
myOutStream.close();
return 0;
}
int main(int argc, char *argv[]) {
char *KCFFile;
char *filein;
char fileout[15];
char *temp;
if (argc<3) {
cerr << "Must be in format: cel2pcx <.kcf file> <.cel to convert> ...\n";
cerr << "The .kcf and .cel suffixes must be included.\n";
return 0; }
KCFFile=argv[1];
if (readKCF(KCFFile)) return 0;
headerInit(); //inits headerblock;
for (int i=2; i<argc; i++) { //remaining args for file names
filein=argv[i];
temp=filein;
for (int j=0; *temp!='.'; j++, temp++)
fileout[j]=*temp;
fileout[j]='\0';
strcat(fileout, ".pcx\0");
if (!convertCELPic(filein, fileout))
cerr << filein << " converted \n";
else
cerr << filein << " not converted.\n";
}
cerr << "Done.\n";
return 0;
}